package com.shop.shiro;

import com.shop.pojo.DtsAdmin;
import com.shop.service.DtsAdminService;
import com.shop.service.DtsPermissionService;
import com.shop.service.DtsRoleService;
import com.shop.util.bcrypt.BCryptPasswordEncoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * @ClassName AdminAuthorizingRealm
 * @Author xiao宋
 * @Date 17:48  2022/10/12
 * @Version 1.0
 * @Description TODO
 */
@Slf4j
public class AdminAuthorizingRealm extends AuthorizingRealm {
    @Autowired
    DtsAdminService adminService;
    @Autowired
    DtsRoleService roleService;
    @Autowired
    DtsPermissionService permissionService;

    /**
     * 授权
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        DtsAdmin admin = (DtsAdmin) principals.getPrimaryPrincipal();
//        拿到用户的 角色 ID  （是个数组）
        Integer[] rolesIds = admin.getRoleIds();
//          通过用户的角色 ID 分别得到权限和对应角色并返回
        Set<String> roles = roleService.findRolesById(rolesIds);
        authorizationInfo.setRoles(roles);
        Set<String>perms=permissionService.findPermsById(rolesIds);
        authorizationInfo.setStringPermissions(perms);
        return authorizationInfo;
    }

    /**
     * 认证
     *
     * @param token the authentication token containing the user's principal and credentials.
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//        从token里拿用户输入的用户名和密码
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());
        log.info("从token里拿的用户名：{}、密码：{}" + username, password);

        DtsAdmin admin = adminService.findByUsername(username);
        if (admin == null) {
            throw new UnknownAccountException("该账户是未知的");
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!passwordEncoder.matches(password, admin.getPassword())) {
            throw new CredentialsException("密码输入错误");
        }
        if (admin.getDeleted()) {
            throw new LockedAccountException("该账户已失效");
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(admin, password, admin.getUsername());
        return authenticationInfo;
    }
}
